/**    
 * 文件名：DdingLockSyncService.java</br>
 *    
 * 版本信息：v1.0</br>
 * 日期：2017年10月18日</br>
 * © 2005-2017 雷技信息科技（上海）有限公司版权所有</br>
 *
 */
package com.logic.landseaserver.models.ddlock;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.logic.system.service.IConfigurationService;
import com.logic.system.service.impl.ConfigurationService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.logic.landseaserver.common.LandeaConstants.SmsSendStatus;
import com.logic.landseaserver.common.exception.LandseaException;
import com.logic.landseaserver.common.util.JsonObjectUtils;
import com.logic.landseaserver.common.util.SMSUtil;
import com.logic.landseaserver.common.util.StringTools;
import com.logic.landseaserver.domain.Project;
import com.logic.landseaserver.domain.SendSmsRecord;
import com.logic.landseaserver.models.ddlock.bean.SmsRoomInfo;
import com.logic.landseaserver.persistence.read.ProjectReadMapper;
import com.logic.landseaserver.persistence.read.RoomReadMapper;
import com.logic.landseaserver.persistence.write.SendSmsRecordWriteMapper;

/**
 *
 * 项目名称：system-server</br>
 * 类名称：DdingLockSyncService</br>
 * 类描述：云丁锁事件</br>
 * 创建人：Aaron</br>
 * 创建时间：2017年10月18日 下午6:18:39</br>
 * 
 * @version 1.0
 *
 */
@Service
public class DdingLockEvtService
{
    private static final Logger LOG = LoggerFactory.getLogger(DdingLockEvtService.class);
    
    @Autowired
    private RoomReadMapper roomReadMapper;
    
    @Autowired
    private SendSmsRecordWriteMapper sendSmsRecordWriteMapper;
    
    @Autowired
    private ProjectReadMapper projectReadMapper;

    @Autowired
    private IConfigurationService configurationService;

    /**
     * 
     * [简要描述]：门锁离线、电池电量低于伐值，发送短信给店长</br>
     * [详细描述]：</br>
     * [作者]：Aaron(2017-10-23)</br>
     *
     * @param smsCode
     * @param projectId
     * @param roomId
     *
     */
    public void sendSmsToDz(String smsCode, Integer projectId, Integer roomId)
    {
        try
        {
            // 查询门店、房间信息
            SmsRoomInfo smsRoomInfo = roomReadMapper.querySmsRoomInfo(roomId);
            if (null == smsRoomInfo)
            {
                LOG.info("云丁门锁事件回调|发送短信|房间不存在.roomId=" + roomId);
                return;
            }
            
            // 查询项目的contractPhone
            Project project = projectReadMapper.selectProject(projectId);
            if (null == project)
            {
                LOG.info("云丁门锁事件回调|发送短信|项目ID=" + projectId + " 项目不存在.");
                return;
            }
            String phone = project.getContractPhone();
            if (StringUtils.isEmpty(phone) || !StringTools.isPhone(phone))
            {
                LOG.info("云丁门锁事件回调|发送短信|项目ID=" + projectId + " 手机号非法.phone=" + phone);
                return;
            }
            
            String smsContent = null;
            String projectName = null == smsRoomInfo.getProjectName() ? "" : smsRoomInfo.getProjectName();
            String houseNum = null == smsRoomInfo.getHouseNum() ? "" : smsRoomInfo.getHouseNum();
            smsContent = "\"{'project':'" + projectName + "','count':'1','house_num':'" + houseNum + "'}\"";
            // 此处不发短信，入发短信库，交给定时任务
            
            SendSmsRecord sendSmsRecord = new SendSmsRecord();
            sendSmsRecord.setWid(StringTools.generateUuid());
            sendSmsRecord.setContent(smsContent);
            sendSmsRecord.setPhone(phone);
            sendSmsRecord.setSmsCode(smsCode);
            // 默认未发送
            sendSmsRecord.setStatus(SmsSendStatus.NONE_SEND);
            sendSmsRecord.initCommonFieldWithUser(-1);
            sendSmsRecordWriteMapper.insertSelective(sendSmsRecord);
        }
        catch (Exception e)
        {
            LOG.error("云丁门锁事件回调|发送短信给店长失败.smsCode=" + smsCode + ",projectId=" + projectId + ",roomId=" + roomId, e);
        }
    }
    
    /**
     * 
     * [简要描述]：合并短信</br>
     * [详细描述]：</br>
     * [作者]：Aaron(2017-11-24)</br>
     *
     * @param needSendList
     *
     */
    public void mergeAndSend(List<SendSmsRecord> needSendList, String lockOfflineCode)
    {
        // key为手机号_项目名称，value为要合并的短信
        Map<String, List<SendSmsRecord>> mergeMap = new HashMap<String, List<SendSmsRecord>>();
        
        Iterator<SendSmsRecord> iterator = needSendList.iterator();
        while (iterator.hasNext())
        {
            SendSmsRecord sendSmsRecord = iterator.next();
            
            String phone = sendSmsRecord.getPhone();
            
            if (StringUtils.isEmpty(phone))
            {
                LOG.error("merge|短信记录中手机号为空,丢弃该短信.");
                iterator.remove();
                continue;
            }
            
            if (StringUtils.equals(lockOfflineCode, sendSmsRecord.getSmsCode()))
            {
                String projectName = getFromSmsContent(sendSmsRecord.getContent(), "project");
                String key = projectName + "_" + phone;
                List<SendSmsRecord> list = mergeMap.get(key);
                if (null == list)
                {
                    list = new ArrayList<SendSmsRecord>();
                    mergeMap.put(key, list);
                }
                list.add(sendSmsRecord);
                iterator.remove();
            }
        }
        
        // 开始合并
        Set<Entry<String, List<SendSmsRecord>>> set = mergeMap.entrySet();
        for (Entry<String, List<SendSmsRecord>> entry : set)
        {
            List<SendSmsRecord> list = entry.getValue();
            SendSmsRecord sendSmsRecord = doMerge(list);
            
            sendMerge(sendSmsRecord, list);
        }
    }
    
    /**
     * 
     * [简要描述]：从门锁离线/低电量预警的短信内容中获取值</br>
     * [详细描述]：</br>
     * [作者]：Aaron(2017-11-24)</br>
     *
     * @param content
     * @return
     *
     */
    private String getFromSmsContent(String content, String destKey)
    {
        String result = "";
        
        try
        {
            // 先替换'为"
            String str = content.replaceAll("'", "\"");
            str = str.substring(1, str.length());
            str = str.substring(0, str.length() - 1);
            Map<String, Object> map = JsonObjectUtils.jsonStr2map(str);
            result = StringTools.getString(map.get(destKey));
            return result;
        }
        catch (LandseaException e)
        {
            LOG.error("getProjectName|从短信内容中获取" + destKey + "失败.", e);
            return "";
        }
    }
    
    private SendSmsRecord doMerge(List<SendSmsRecord> list)
    {
        try
        {
            StringBuilder roomStrBuilder = new StringBuilder();
            int size = list.size();
            String content = null;
            List<String> roomHouseList = new ArrayList<String>();
            for (int i = 0; i < size; i++)
            {
                content = list.get(i).getContent();
                String roomHouse = getFromSmsContent(content, "house_num");
                if (roomHouseList.contains(roomHouse))
                {
                    continue;
                }
                
                roomStrBuilder.append(roomHouse);
                roomHouseList.add(roomHouse);
                if (i != size - 1)
                {
                    roomStrBuilder.append("、");
                }
            }
            String projectName = getFromSmsContent(content, "project");
            
            String smsContent = "\"{'project':'" + projectName + "','count':'" + String.valueOf(roomHouseList.size()) + "','house_num':'"
                + roomStrBuilder.toString() + "'}\"";
            
            SendSmsRecord first = list.get(0);
            SendSmsRecord sendSmsRecord = new SendSmsRecord();
            sendSmsRecord.setId(first.getId());
            sendSmsRecord.setWid(first.getWid());
            sendSmsRecord.setSmsCode(first.getSmsCode());
            sendSmsRecord.setContent(smsContent);
            sendSmsRecord.setPhone(first.getPhone());
            
            return sendSmsRecord;
        }
        catch (Exception e)
        {
            LOG.error("doMerge|合并短信失败.", e);
            return null;
        }
    }
    
    private void sendMerge(SendSmsRecord needSend, List<SendSmsRecord> needUpdateList)
    {
        try
        {
            LOG.info("sendSmsTask|开始合并发送短信=>" + needSend.toString());
            String signName = configurationService.getStringValue(ConfigurationService.SEND_MSG_SIGN_NAME);
            boolean sendResult = SMSUtil.sendSms(needSend.getSmsCode(), needSend.getPhone(), needSend.getContent(),signName);
            if (!sendResult)
            {
                // 发送失败
                LOG.error("sendSmsTask|发送合并短信失败." + needSend);
                for (SendSmsRecord update : needUpdateList)
                {
                    updateSmsRecord(update.getId(), SmsSendStatus.SEND_FAILED);
                }
            }
            
            LOG.info("sendSmsTask|发送合并短信成功.WID=" + needSend.getWid());
            for (SendSmsRecord update : needUpdateList)
            {
                updateSmsRecord(update.getId(), SmsSendStatus.SEND_SUCCESS);
            }
        }
        catch (Exception e)
        {
            LOG.error("sendSmsTask|发送合并短信失败.WID=" + needSend.getWid());
            updateSmsRecord(needSend.getId(), SmsSendStatus.SEND_FAILED);
        }
    }
    
    private void updateSmsRecord(Integer id, Integer status)
    {
        try
        {
            SendSmsRecord update = new SendSmsRecord();
            update.setId(id);
            update.setStatus(status);
            update.setLastModifiedDtm(new Date());
            sendSmsRecordWriteMapper.updateByPrimaryKeySelective(update);
        }
        catch (Exception e)
        {
            LOG.error("sendSmsTask|更新短信记录失败.ID=" + id + ",status=" + status);
        }
    }
}
